<template>
  <div class="menu-list">
    <div class="header">
      <h2>菜单管理</h2>
      <el-button type="primary" @click="handleAdd">
        <el-icon><Plus /></el-icon>
        添加菜单
      </el-button>
    </div>

    <el-form :model="searchForm" inline class="search-form">
      <el-form-item label="菜单名称">
        <el-input v-model="searchForm.name" placeholder="请输入菜单名称" clearable />
      </el-form-item>
    
      <el-form-item>
        <el-button type="primary" @click="handleSearch">搜索</el-button>
        <el-button @click="resetSearch">重置</el-button>
      </el-form-item>
    </el-form>

    <el-table :data="menuList" border style="width: 100%">
      <el-table-column prop="id" label="ID" width="80" />
      <el-table-column prop="code" label="编码" />
      <el-table-column prop="name" label="名称" />
      <el-table-column prop="order" label="排序" width="80" />
      <el-table-column prop="remark" label="备注" />
      <el-table-column prop="type" label="类型" width="100" />
      <el-table-column prop="level" label="层级" width="80" />
      <el-table-column label="操作" width="200">
        <template #default="{ row }">
          <el-button-group>
            <el-button type="primary" size="small" @click="handleEdit(row)">
              <el-icon><Edit /></el-icon>
              编辑
            </el-button>
            <el-button type="danger" size="small" @click="handleDelete(row)">
              <el-icon><Delete /></el-icon>
              删除
            </el-button>
          </el-button-group>
        </template>
      </el-table-column>
    </el-table>

    <div class="pagination">
      <el-pagination
        v-model:current-page="currentPage"
        v-model:page-size="pageSize"
        :total="total"
        :page-sizes="[10, 20, 50, 100]"
        layout="total, sizes, prev, pager, next, jumper"
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
      />
    </div>

    <el-dialog
      v-model="dialogVisible"
      :title="dialogType === 'add' ? '添加菜单' : '编辑菜单'"
      width="500px"
    >
      <el-form
        ref="formRef"
        :model="form"
        :rules="rules"
        label-width="80px"
      >
        <el-form-item label="编码" prop="code">
          <el-input v-model="form.code" />
        </el-form-item>
        <el-form-item label="名称" prop="name">
          <el-input v-model="form.name" />
        </el-form-item>
        <el-form-item label="路由" prop="route">
          <el-input v-model="form.route" />
        </el-form-item>
        <el-form-item label="上级菜单" prop="pid">
          <el-popover
            placement="bottom-start"
            :width="220"
            trigger="click"
            v-model:visible="menuPopoverVisible"
          >
            <template #reference>
              <el-button @click= "lazy = !lazy">{{ selectedMenuName ? selectedMenuName : '选择上级菜单' }}</el-button>
            </template>
            <menu-tree 
              :is-collapse="false" 
              :lazy=lazy
              @menu-select="handleMenuSelect"
            />
          </el-popover>
        </el-form-item>
        <el-form-item label="排序" prop="order">
          <el-input-number v-model="form.order" :min="1" />
        </el-form-item>
        <el-form-item label="备注" prop="remark">
          <el-input v-model="form.remark" type="textarea" />
        </el-form-item>
        <el-form-item label="类型" prop="type">
          <el-select v-model="form.type" style="width: 100%">
            <el-option label="目录" :value="'目录'" />
            <el-option label="菜单" :value="'菜单'" />
            <el-option label="按钮" :value="'按钮'" />
          </el-select>
        </el-form-item>
        <el-form-item label="层级" prop="level">
          <el-input-number v-model="form.level" :min="1" />
        </el-form-item>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="handleCancel">取消</el-button>
          <el-button type="primary" @click="handleSubmit">确定</el-button>
        </span>
      </template>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, onMounted } from 'vue'
import { Plus, Edit, Delete } from '@element-plus/icons-vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import type { FormInstance, FormRules } from 'element-plus'
import { Menu, MenuItem, defaultMenu } from '../../types/menu'
import { getMenuPage, deleteMenu, addOrUpdateMenu, getMenuName } from '../../api/menu'
import MenuTree from '../../components/MenuTree.vue'


const menuList = ref<Menu[]>([])
const currentPage = ref(1)
const pageSize = ref(10)
const total = ref(0)
const dialogVisible = ref(false)
const dialogType = ref<'add' | 'edit'>('add')
const formRef = ref<FormInstance>()
const lazy = ref(false)

const form = reactive({ ...defaultMenu })

const searchForm = reactive({name: ''})

const menuPopoverVisible = ref(false)
const selectedMenuName = ref('')

const handleSearch = () => {
  currentPage.value = 1
  fetchMenuPage()
}

const resetSearch = () => {
  Object.assign(searchForm, { ...defaultMenu })
  handleSearch()
}

const rules = reactive<FormRules>({
  code: [
    { required: true, message: '请输入编码', trigger: 'blur' },
    { min: 2, max: 20, message: '长度在 2 到 20 个字符', trigger: 'blur' }
  ],
  name: [
    { required: true, message: '请输入名称', trigger: 'blur' },
    { min: 2, max: 20, message: '长度在 2 到 20 个字符', trigger: 'blur' }
  ]
})

const fetchMenuPage = async () => {
  const pageData = await getMenuPage({
    page: currentPage.value,
    size: pageSize.value,
    ...searchForm
  })

  menuList.value = pageData.records
  total.value = pageData.count
}

const handleSizeChange = (val: number) => {
  pageSize.value = val
  fetchMenuPage()
}

const handleCurrentChange = (val: number) => {
  currentPage.value = val
  fetchMenuPage()
}

const handleMenuSelect = (menu: MenuItem) => {
  form.pid = menu.id
  selectedMenuName.value = menu.name
  menuPopoverVisible.value = false
}

const handleAdd = () => {
  dialogType.value = 'add'
  Object.assign(form, { ...defaultMenu })
  selectedMenuName.value = ''
  dialogVisible.value = true
}

const handleEdit = async (row: Menu) => {
  dialogType.value = 'edit'
  Object.assign(form, row)
  selectedMenuName.value = await getMenuName(row.pid) 
  dialogVisible.value = true
}

const handleDelete = (row: Menu) => {
  if (!row.id) return
  ElMessageBox.confirm('确定要删除该菜单吗？', '提示', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning'
  }).then(async () => {
    const result = await deleteMenu(row.id)
    if (result) {
      fetchMenuPage()
    }
  }).catch(() => {
    ElMessage.info('已取消删除操作')
  })
}

const handleSubmit = async () => {
  if (!formRef.value) return
  await formRef.value.validate().then(async (valid) => {
    if (valid) {
      const result = await addOrUpdateMenu(form, dialogType.value === 'add')
      if (result) {
        dialogVisible.value = false
        fetchMenuPage()
      }
    }
  }).catch(() => {
    ElMessage.error('表单验证失败')
  })
}

const handleCancel = () => {
  dialogVisible.value = false
}

onMounted(() => {
  fetchMenuPage()
})
</script>

<style scoped>
.menu-list {
  padding: 20px;
}

.header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
}

.header h2 {
  margin: 0;
  color: var(--el-text-color-primary);
}

.pagination {
  margin-top: 20px;
  display: flex;
  justify-content: flex-end;
}

.dialog-footer {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
}

.search-form {
  margin-bottom: 20px;
  padding: 20px;
  background-color: var(--el-bg-color-page);
  border-radius: 4px;
}

:deep(.el-input__inner:focus) {
  box-shadow: none !important;
  border-color: var(--el-border-color) !important;
}
</style>